package com.zh.harmony.fragment;

import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.PageSliderProvider;

import java.util.concurrent.atomic.AtomicInteger;

/**
 * Fragment配合PageSlider使用时使用
 */
public abstract class FragmentSliderProvider extends PageSliderProvider {
    private final FragmentManager mFragmentManager;
    private FragmentTransaction mCurTransaction = null;

    public FragmentSliderProvider(FragmentManager fm) {
        this.mFragmentManager = fm;
    }

    /**
     * Return the Fragment associated with a specified position.
     */
    public abstract Fragment getItem(int position);

    @Override
    public void startUpdate(ComponentContainer container) {
        //因为鸿蒙给的container并不是PageSlider，而是内部的3个子View，他们是没有id的，所以需要手动生成
        if (container.getId() == Component.ID_DEFAULT) {
            container.setId(generateViewId());
        }
    }

    @SuppressWarnings("ReferenceEquality")
    @Override
    public Object createPageInContainer(ComponentContainer container, int position) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }

        final long itemId = getItemId(position);

        // Do we already have this fragment?
        String name = makeFragmentName(container.getId(), itemId);
        Fragment fragment = mFragmentManager.findFragmentByTag(name);
        if (fragment != null) {
            mCurTransaction.attach(fragment);
        } else {
            fragment = getItem(position);
            mCurTransaction.add(container.getId(), fragment,
                    makeFragmentName(container.getId(), itemId));
        }
        return fragment;
    }

    @Override
    public void destroyPageFromContainer(ComponentContainer container, int position, Object object) {
        if (mCurTransaction == null) {
            mCurTransaction = mFragmentManager.beginTransaction();
        }
        mCurTransaction.remove((Fragment) object);
    }

    @Override
    public void onUpdateFinished(ComponentContainer container) {
        if (mCurTransaction != null) {
            mCurTransaction.commit();
            mCurTransaction = null;
        }
    }

    @Override
    public boolean isPageMatchToObject(Component view, Object object) {
        return ((Fragment) object).getView() == view;
    }

    @Override
    public int getPageIndex(Object object) {
        //保持不销毁
        return PageSliderProvider.POSITION_REMAIN;
    }

    /**
     * Return a unique identifier for the item at the given position.
     *
     * <p>The default implementation returns the given position.
     * Subclasses should override this method if the positions of items can change.</p>
     *
     * @param position Position within this adapter
     * @return Unique identifier for the item at position
     */
    public long getItemId(int position) {
        return position;
    }

    private static String makeFragmentName(int viewId, long id) {
        return "android:switcher:" + viewId + ":" + id;
    }

    /**
     * Id生成
     */
    private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);

    /**
     * 生成一个View的Id
     */
    public static int generateViewId() {
        for (; ; ) {
            final int result = sNextGeneratedId.get();
            // aapt-generated IDs have the high byte nonzero; clamp to the range under that.
            int newValue = result + 1;
            if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
            if (sNextGeneratedId.compareAndSet(result, newValue)) {
                return result;
            }
        }
    }
}